package com.xjve.framework.hibernate.query.core;


import com.xjve.framework.hibernate.query.exception.SqlQueryException;
import com.xjve.framework.hibernate.query.model.SqlTemplate;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.dialect.AbstractProcessorDialect;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.IProcessor;
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.templatemode.TemplateMode;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * SQL包含方言，支持#include语法
 */
public class SqlIncludeDialect extends AbstractProcessorDialect {

    private static final String DIALECT_NAME = "SQL Include Dialect";
    private static final String DIALECT_PREFIX = "sql";
    private static final int PROCESSOR_PRECEDENCE = 1000;

    // 匹配{{ #include templateName }}语法
    private static final Pattern INCLUDE_PATTERN = Pattern.compile("\\{\\{\\s*#include\\s+([\\w-]+)\\s*}\\}");

    private final Map<String, SqlTemplate> sqlTemplates;

    public SqlIncludeDialect(Map<String, SqlTemplate> sqlTemplates) {
        super(DIALECT_NAME, DIALECT_PREFIX, PROCESSOR_PRECEDENCE);
        this.sqlTemplates = sqlTemplates;
    }

    @Override
    public Set<IProcessor> getProcessors(String dialectPrefix) {
        Set<IProcessor> processors = new HashSet<>();
        processors.add(new SqlIncludeProcessor(dialectPrefix));
        return processors;
    }

    /**
     * SQL包含处理器
     */
    private static class SqlIncludeProcessor extends AbstractAttributeTagProcessor {

        public SqlIncludeProcessor(String dialectPrefix) {
            super(
                    TemplateMode.TEXT,    // 模板模式
                    dialectPrefix,        // 方言前缀
                    null,                 // 标签名称（null表示匹配所有标签）
                    false,                // 是否只匹配有前缀的标签
                    "include",            // 属性名称
                    true,                 // 是否优先于其他处理器
                    PROCESSOR_PRECEDENCE, // 优先级
                    true                  // 是否移除属性
            );
        }

        @Override
        protected void doProcess(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName,
                                 String attributeValue, IElementTagStructureHandler structureHandler) {
            // 这个方法主要用于标签处理，我们主要使用文本处理
        }
    }

    /**
     * 处理SQL模板中的#include语法
     * @param sqlContent SQL内容
     * @return 处理后的SQL内容
     */
    public String processIncludes(String sqlContent) {
        Matcher matcher = INCLUDE_PATTERN.matcher(sqlContent);
        StringBuffer sb = new StringBuffer();

        while (matcher.find()) {
            String templateName = matcher.group(1);
            SqlTemplate template = sqlTemplates.get(templateName);

            if (template == null) {
                throw new SqlQueryException("Included SQL template not found: " + templateName);
            }

            // 递归处理嵌套的include
            String includedContent = processIncludes(template.getContent());

            // 替换匹配的内容
            matcher.appendReplacement(sb, includedContent);
        }

        matcher.appendTail(sb);
        return sb.toString();
    }
}
